﻿using Microsoft.Practices.Prism.StoreApps;
using Microsoft.Practices.Prism.StoreApps.Interfaces;
using Sumc.Client.ModernUI.Common;
using Sumc.Client.ModernUI.Extensions;
using Sumc.Client.ModernUI.Helpers;
using Sumc.Client.ModernUI.Services;
using Sumc.Models.Responses;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml.Navigation;

namespace Sumc.Client.ModernUI.ViewModels
{
    public class SearchPageViewModel : BaseViewModel
    {
        private bool isFound;
        private string searchQuery;
        private ObservableCollection<ScheduleDirections> transportsResults;
        private ObservableCollection<Stop> stopsResults;
        private DelegateCommand<Stop> goToStopInformation;
        private DelegateCommand<ScheduleDirections> goToTransport;
        private readonly IScheduleRepository scheduleRepository;
        private readonly IVirtualTableRepository virtualTableRepository;

        public SearchPageViewModel(INavigationService navigationService,
            IVirtualTableRepository virtualTableRepository,
            IScheduleRepository scheduleRepository,
            IAlertMessageService alertMessageService,
            ISearchPaneService searchPaneService,
            IFlyoutService flyoutService)
            : base(navigationService,
            alertMessageService,
            flyoutService,
            searchPaneService)
        {
            this.scheduleRepository = scheduleRepository;
            this.virtualTableRepository = virtualTableRepository;
        }

        public DelegateCommand<ScheduleDirections> GoToTransport
        {
            get
            {
                if (this.goToTransport == null)
                {
                    this.goToTransport = new DelegateCommand<ScheduleDirections>(this.NavigateToTransport);
                }

                return this.goToTransport;
            }
        }

        public DelegateCommand<Stop> GoToStopInformation
        {
            get
            {
                if (this.goToStopInformation == null)
                {
                    this.goToStopInformation = new DelegateCommand<Stop>(this.NavigateToStopInformation);
                }

                return this.goToStopInformation;
            }
        }

        public bool IsFound
        {
            get
            {
                return this.isFound;
            }

            set
            {
                this.SetProperty(ref this.isFound, value);
            }
        }

        public string SearchQuery
        {
            get
            {
                return this.searchQuery;
            }

            set
            {
                this.SetProperty(ref this.searchQuery, value);
            }
        }

        public ObservableCollection<ScheduleDirections> TransportsResults
        {
            get
            {
                return this.transportsResults;
            }

            set
            {
                this.SetProperty(ref this.transportsResults, value);
            }
        }

        public ObservableCollection<Stop> StopsResults
        {
            get
            {
                return this.stopsResults;
            }

            set
            {
                this.SetProperty(ref this.stopsResults, value);
            }
        }

        private void NavigateToStopInformation(Stop stop)
        {
            this.navigationService.Navigate(Constants.StopPage, stop.Number);
        }

        private async void NavigateToTransport(ScheduleDirections scheduleDirection)
        {
            await this.navigationService.NavigateJson(Constants.TransportPage, scheduleDirection);
        }

        private void GetResults(string query)
        {
            this.LoadData(async () =>
            {
                var busResults = await this.scheduleRepository.GetTransportDirections(TransportType.Bus, query);
                var tramResults = await this.scheduleRepository.GetTransportDirections(TransportType.Tram, query);
                var trolleyResults = await this.scheduleRepository.GetTransportDirections(TransportType.Trolley, query);
                var virtualTable = await this.virtualTableRepository.GetStopVirtualTable(query);
                this.IsFound = busResults != null && busResults.Error == null ||
                    tramResults != null && tramResults.Error == null ||
                    trolleyResults != null && trolleyResults.Error == null ||
                    virtualTable != null && virtualTable.IsFound;
                this.LoadingData = false;

                this.AddTransportResult(busResults);
                this.AddTransportResult(tramResults);
                this.AddTransportResult(trolleyResults);

                if (virtualTable != null && virtualTable.FoundStops != null && virtualTable.FoundStops.FirstOrDefault() != null)
                {
                    this.StopsResults = new ObservableCollection<Stop>();
                    this.StopsResults.FillCollection(virtualTable.FoundStops);
                }
            });
        }

        private void AddTransportResult(ScheduleDirections transportInformation)
        {
            if (this.TransportsResults == null)
            {
                this.TransportsResults = new ObservableCollection<ScheduleDirections>();
            }

            if (transportInformation != null && transportInformation.Error == null)
            {
                this.transportsResults.Add(transportInformation);
            }
        }

        public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
        {
            base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
            var query = navigationParameter as string;
            this.SearchQuery = query;
            this.GetResults(query);
        }
    }
}
